<?php

namespace app\service;

use app\core\exception\BusinessException;
use app\core\Service;
use app\model\BlessingOrder;
use app\model\Goods;
use app\model\LotusLamp;
use app\model\Member;
use app\model\Order;
use app\model\ProductOrder;
use app\model\TeamIncome;
use app\model\Temple;
use app\model\TempleIncome;
use think\facade\Db;
use think\facade\Log;

/**
 * 祈福供灯订单
 * @extends Service<BlessingOrderService>
 */
class BlessingOrderService extends Service
{

    const TYPE = [
        1 => '大愿供灯',
        2 => '祈福供灯',
        3 => '阖家供灯',
        4 => '还愿供灯',
    ];
    const STATUS = [
        1 => '待支付',
        2 => '已支付',
        3 => '已取消',
    ];

    public function list($page, $limit, $searchQuery = null)
    {
        if (!empty($searchQuery['temple_name']) && $searchQuery['temple_name'] != '') {
            $w = [];
            $w[] = ['name', 'like', "%" . $searchQuery['temple_name'] . "%"];
            $temple = (new Temple())->where($w)->field('temple_id')->find();
            $searchQuery['temple_id'] = $temple['temple_id'];
        }
        $w = [];
        if (!empty($searchQuery['status']) && $searchQuery['status'] != '') {
            $w[] = ['status', '=', $searchQuery['status']];
        }
        if (!empty($searchQuery['member_id']) && $searchQuery['member_id'] != '') {
            $w[] = ['member_id', '=', $searchQuery['member_id']];
        }
        if (!empty($searchQuery['order_type']) && $searchQuery['order_type'] != '') {
            $w[] = ['order_type', '=', $searchQuery['order_type']];
        }
        if (!empty($searchQuery['temple_id']) && $searchQuery['temple_id'] != '') {
            $w[] = ['temple_id', '=', $searchQuery['temple_id']];
        }
        if (!empty($searchQuery['order_no']) && $searchQuery['order_no'] != '') {
            $w[] = ['order_no', '=', $searchQuery['order_no']];
        }
        if (!empty($searchQuery['paytimeValues'])) {
            if (!is_array($searchQuery['paytimeValues'])) {
                $timeValues = json_decode($searchQuery['paytimeValues']);
            } else {
                $timeValues = $searchQuery['paytimeValues'];
            }
            $w[] = ['pay_time', 'between', $timeValues];
        }
        if (!empty($searchQuery['timeValues'])) {
            if (!is_array($searchQuery['timeValues'])) {
                $timeValues = json_decode($searchQuery['timeValues']);
            } else {
                $timeValues = $searchQuery['timeValues'];
            }
            $w[] = ['create_time', 'between', $timeValues];
        }
        $w[] = ['is_delete', '=', 0];
        $map = BlessingOrder::where($w)->page($page, $limit)->order('order_id desc');
        $list = $map->select()->toArray();
        if ($list) {
            $temple_ids = array_column($list, 'temple_id');
            $templeList = (new Temple())->where('temple_id', 'in', $temple_ids)->select()->toArray();
            $templeList = array_column($templeList, null, 'temple_id');
            foreach ($list as &$v) {
                $v['temple_name'] = $templeList[$v['temple_id']]['name'] ?: '';
                $lotusLampStr = '';
                if (explode(',', $v['lotus_lamp_ids']) && $v['lotus_lamp_ids'] != '') {
                    $lotus_lamp_ids = explode(',', $v['lotus_lamp_ids']);
                    $lotusLampList = (new LotusLamp())::where('id', 'in', $lotus_lamp_ids)->select();
                    foreach ($lotusLampList as &$value) {
                        $lotusLampStr .= $value['device_no'] . '(' . $value['id'] . '号莲花灯);';
                    }
                    $v['lotus_lamp_str'] = $lotusLampStr;
                } else {
                    $v['lotus_lamp_str'] = $lotusLampStr;
                }
                $v['audio_model'] = $lotusLampStr;
                if ($v['type']) {
                    $v['img'] = 'https://pray.veac.cn/storage/home/pary' . $v['type'] . '.png';
                } else {
                    $v['img'] = '';
                }
            }
        }
        return [
            'total' => $map->count(),
            'list' => $list,
        ];

    }

    public function sumPrice($searchQuery = [])
    {
        $w = [];
        $w[] = ['order_type', '=', 1];
        if (!empty($searchQuery['create_time'])) {
            $time_arr = explode("#", $searchQuery['create_time']);
            if (count($time_arr) > 0) {
                $w[] = ['create_time', 'between', $time_arr];
            }
        }
        $price = BlessingOrder::where($w)->sum('price');
        return $price;
    }

    public function getExportList($searchQuery = null)
    {
        $w = [];
        if (!empty($searchQuery['status']) && $searchQuery['status'] != '') {
            $w[] = ['status', '=', $searchQuery['status']];
        }
        if (!empty($searchQuery['member_id']) && $searchQuery['member_id'] != '') {
            $w[] = ['member_id', '=', $searchQuery['member_id']];
        }
        if (!empty($searchQuery['order_type']) && $searchQuery['order_type'] != '') {
            $w[] = ['order_type', '=', $searchQuery['order_type']];
        }
        if (!empty($searchQuery['temple_id']) && $searchQuery['temple_id'] != '') {
            $w[] = ['temple_id', '=', $searchQuery['temple_id']];
        }
        if (!empty($searchQuery['order_no']) && $searchQuery['order_no'] != '') {
            $w[] = ['order_no', '=', $searchQuery['order_no']];
        }
        $w[] = ['is_delete', '=', 0];
        $list = BlessingOrder::where($w)->select();
        if (!empty($list)) {
            $list = $list->toArray();
            foreach ($list as &$v) {
                $temple = (new Temple())->where(['temple_id' => $v['temple_id']])->field('name')->find();
                if ($temple) {
                    $v['temple_name'] = $temple['name'];
                } else {
                    $v['temple_name'] = '';
                }
                $v['type_name'] = self::TYPE[$v['type']];
                $v['status_name'] = self::STATUS[$v['status']];
            }
        }
        return [
            'list' => $list,
        ];
    }

    public function save($data, $member_id)
    {
        $order_no = 'OD' . time() . rand(1000, 9999) . $member_id;
        if (!$data['price']) {
            throw new BusinessException('金额错误');
        }
        if ($data['order_type'] == 1) {
            if (!$data['type']) {
                throw new BusinessException('心愿类型错误');
            }
            if (!$data['category']) {
                throw new BusinessException('心愿类别错误');
            }
            if (!$data['wish_name']) {
                throw new BusinessException('心愿名称错误');
            }
            if (!$data['lamp_time']) {
                throw new BusinessException('供灯时间错误');
            }
            if (empty($data['lotus_lamp_ids'])) {
                throw new BusinessException('莲花灯必选');
            }
            $map = [
                'order_type' => $data['order_type'],
                'order_no' => $order_no,
                'member_id' => $member_id,
                'type' => $data['type'] ?: 0,
                'lotus_lamp_ids' => $data['lotus_lamp_ids'] ?: '',
                'temple_id' => $data['temple_id'] ?: 0,
                'price' => $data['price'],
                'category' => $data['category'] ?: 0,
                'wish_name' => $data['wish_name'] ?: '',
                'lamp_time' => $data['lamp_time'] ?: 0,
                'is_anonymity' => $data['is_anonymity'] ?: 0,
                'remark' => !empty($data['remark']) ? $data['remark'] : '',
                'status' => 1
            ];
            $map['name'] = !empty($data['name']) ? $data['name'] : '';
            $map['mobile'] = !empty($data['mobile']) ? $data['mobile'] : '';
            $map['sex'] = !empty($data['sex']) ? $data['sex'] : '';
            $map['birthdate'] = !empty($data['birthdate']) ? $data['birthdate'] : null;
            $map['address'] = !empty($data['address']) ? $data['address'] : '';
        } elseif ($data['order_type'] == 2) {
            $map = [
                'order_type' => $data['order_type'],
                'order_no' => $order_no,
                'member_id' => $member_id,
                'temple_id' => $data['temple_id'] ?: 0,
                'price' => $data['price'],
                'name' => $data['name'] ?: '',
                'mobile' => $data['mobile'] ?: '',
                'sex' => $data['sex'] ?: '',
                'birthdate' => $data['birthdate'] ?: null,
                'address' => $data['address'] ?: '',
                'status' => 1
            ];
        } else {
            throw new BusinessException('订单类型错误');
        }
        $blessingOrder = BlessingOrder::where(['member_id' => $member_id, 'status' => 1])->order('order_id desc')->find();
        $time = time() - 600;
        if ($blessingOrder && strtotime($blessingOrder->create_time) > $time) {
//            throw new BusinessException('请勿频繁操作');
        }
        Db::startTrans();
        try {
            $rs = BlessingOrder::create($map);
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            throw new BusinessException($e->getMessage());
        }
        return $rs;
    }

    public function info($order_id, $member_id = null)
    {
        $w = ['order_id' => $order_id, 'is_delete' => 0];
        if ($member_id) {
            $w['member_id'] = $member_id;
        }
        $info = BlessingOrder::where($w)->find();
        if (!$info) {
            throw new BusinessException('订单不存在');
        }
        $lotusLampStr = '';
        if (explode(',', $info['lotus_lamp_ids'])) {
            $lotus_lamp_ids = explode(',', $info['lotus_lamp_ids']);
            $lotusLampList = (new LotusLamp())::where('id', 'in', $lotus_lamp_ids)->select();
            foreach ($lotusLampList as &$value) {
                $lotusLampStr .= $value['device_no'] . '(' . $value['id'] . '号莲花灯);';
            }
            $info['lotus_lamp_str'] = $lotusLampStr;
        } else {
            $info['lotus_lamp_str'] = $lotusLampStr;
        }
        $templeInfo = (new Temple())->where('temple_id', '=', $info['temple_id'])->find()->toArray();
        if ($info['type']) {
            $info['img'] = 'https://pray.veac.cn/storage/home/pary' . $info['type'] . '.png';
        } else {
            $info['img'] = '';
        }
        $info['temple_name'] = !empty($templeInfo['name']) ? $templeInfo['name'] : '';
        return $info;
    }

    public function cancelOrder($order_id, $member_id)
    {
        $info = BlessingOrder::where([
            'status' => 1, 'order_id' => $order_id, 'member_id' => $member_id, 'is_delete' => 0
        ])->find();
        if (!$info) {
            throw new BusinessException('订单不存在');
        }
        $info->save(['status' => 3, 'cancel_time' => date('Y-m-d H:i:s', time())]);
        return $info;
    }

    public function delOrder($order_id, $member_id)
    {
        $info = BlessingOrder::where([
            'status' => 3, 'order_id' => $order_id, 'member_id' => $member_id,
        ])->find();
        if (!$info) {
            throw new BusinessException('订单不存在');
        }
        $info->save(['is_delete' => 1]);
        return $info;
    }

    public function payOrder($order_no, $order_type)
    {
        if ($order_type == 4) {
            $info = Order::where(['order_no' => $order_no])->find();
        } else if ($order_type == 3) {
            $info = ProductOrder::where(['order_no' => $order_no])->find();
        } else {
            $info = BlessingOrder::where(['order_no' => $order_no])->find();
        }
        if (!$info) {
            throw new BusinessException('订单不存在');
        }
        $orderInfo = $info->toArray();
        if ($info->status != 1) {
            throw new BusinessException('订单已完成');
        }

        Db::startTrans();
        try {
            if ($order_type == 4) {
                $goodsInfo = Goods::where(['goods_id' => $orderInfo['goods_id']])->find();
                if (!$goodsInfo) {
                    throw new BusinessException('商品不存在');
                }
                $stock = $goodsInfo->stock - 1;
                $sales_initial = $goodsInfo->sales_initial + 1;
                $goodsInfo->save(['stock' => $stock, 'sales_initial' => $sales_initial]);
            }
            $info->save(['status' => 2, 'pay_time' => date('Y-m-d H:i:s', time())]);
            $memberInfo = Member::where(['member_id' => $orderInfo['member_id']])->find();
            $data = [
                'merit_amount' => $memberInfo['merit_amount'] + $orderInfo['price'],
                'merit_num' => $memberInfo['merit_num'] + 1,
            ];
            Member::where(['member_id' => $orderInfo['member_id']])->save($data);
            if ($orderInfo['order_type'] == 1) {
                $lotus_lamp_ids = explode(',', $orderInfo['lotus_lamp_ids']);
                $lotusLampList = (new LotusLamp())::where('id', 'in', $lotus_lamp_ids)->select()->toArray();
                $orderInfo['name'] = str_replace(',', '/', $orderInfo['name']);
                if (!empty($lotusLampList)) {
                    foreach ($lotusLampList as &$value) {
                        $url = 'http://device.api.fjxmlz.com:18081/api/bless?sn=' . $value['device_no'];
                        $params = [
                            'name' => $orderInfo['name'],
                            'bless' => $orderInfo['wish_name'],
                            'type' => $orderInfo['type'],
                            'sn' => $value['device_no'],
                            'validTime' => '',
                            'validType' => 'day',
                            'validCount' => $orderInfo['lamp_time'],
                        ];
                        $header = [
                            'Content-Type: application/json'
                        ];
                        $params = json_encode($params);
                        Log::write("LotusLamp_post: " . $params);
                        $res = $this->request_post($url, $header, $params);
                        $result = json_decode($res, true);
                        if ($result['code'] !== 0 && $result['msg'] !== 'success') {
                            Log::write("祈福供灯返回失败: " . $res);
                        }
                        (new LotusLamp())::where('id', '=', $value['id'])->save(
                            [
                                'monitor_info_code' => $result['code'],
                                'monitor_info_msg' => $result['msg'],
                                'monitor_status' => ($result['code'] == 0) ? 1 : 2,
                            ]
                        );
                    }
                }
                $commission = 0;
                $temple = (new Temple())::where(['temple_id' => $orderInfo['temple_id']])->find();
                if ($temple) {
                    $temple = $temple->toArray();
                    $commission = $orderInfo['price'] * ($temple['rate'] / 100);
                }
                TempleIncome::create(
                    [
                        'temple_id' => $orderInfo['temple_id'],
                        'order_id' => $orderInfo['order_id'],
                        'order_no' => $orderInfo['order_no'],
                        'price' => $orderInfo['price'],
                        'commission' => $commission,
                        'pay_time' => date('Y-m-d H:i:s', time()),
                        'member_id' => $orderInfo['member_id'],
                    ]
                );
            }
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            throw new BusinessException($e->getMessage());
        }
        return true;
    }

    public function request_post($url = '', $header = array(), $data_string = '')
    {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        if (!empty($header)) {
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        } else {
            curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                    'Content-Type: application/json',
                    'Content-Length: ' . strlen($data_string))
            );
        }
        $result = curl_exec($ch);
        return $result;
    }
}